package com.android.tnovoselec.travelassistant.dto;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import android.content.Context;

import com.android.tnovoselec.travelassistant.Config;
import com.google.android.maps.GeoPoint;

public class BankomatiResultHolder {
    private static GeoPoint LOCATION = null;

    private static  List<BankomatDto> RESULT = new ArrayList<BankomatDto>();

    private BankomatiResultHolder() {
	super();
    }

    public synchronized static void init(List<BankomatDto> banks, GeoPoint location, Context context) {
	BankomatiResultHolder.clear();

	if (banks != null) {
	    if (location != null) { // Will always be true (in this application
				    // version)!
		BankomatiResultHolder.LOCATION = location;
		BankomatiResultHolder.RESULT = banks;
		// ResultHolder.filter(banks, location);
		BankomatiResultHolder.sort(banks, location);
	    }

	    // ResultHolder.group(banks, context);
	}
    }

    public static void filter(List<BankomatDto> banks, GeoPoint myLocation) {
	// Not able to do this in query...
	Iterator<BankomatDto> bankIterator = banks.iterator();
	while (bankIterator.hasNext()) {
	    BankomatDto bank = bankIterator.next();
	    if (bank.getDistance(myLocation) > Config.RESULT_DISTANCE_LIMIT) {
		//bankIterator.remove();
	    }
	}
    }

    /**
     * FIXME Actually not necessary, but because of approximation of SQLite
     * distance function, leaving it (there is some small possibility for
     * something unexpected)!<br />
     * Theoretically, there can be mistake measured in few centimeters - so this
     * function is really not necessary, but leaving it - it will not take much
     * of the processor's time...<br />
     * As said, there is small, really small chance that we missed one result
     * (probably will never happen at this range so not complicating here)...
     */
    private static void sort(List<BankomatDto> banks, final GeoPoint myLocation) {
	Collections.sort(banks, new Comparator<BankomatDto>() {

	    @Override
	    public int compare(BankomatDto bank1, BankomatDto bank2) {
		double distance1 = bank1.getDistance(myLocation);
		double distance2 = bank2.getDistance(myLocation);

		if (distance1 < distance2) {
		    return -1;
		} else if (distance1 > distance2) {
		    return 1;
		}

		return 0;
	    }
	});
    }

    // private static final Map<String, BankGroup> TEMP = new HashMap<String,
    // BankGroup>(10, 0.75F);

    // private static void group(List<Bank> banks, Context context) {
    // // No need for synchronization!
    // ResultHolder.RESULT.add(new
    // BankGroup(context.getResources().getString(R.string.all_banks), banks));
    //
    // for (Bank bank : banks) {
    // BankGroup bankGroup = ResultHolder.TEMP.get(bank.getBankGroupName());
    // if (bankGroup == null) {
    // bankGroup = new BankGroup(bank.getBankGroupName());
    // ResultHolder.RESULT.add(bankGroup);
    // ResultHolder.TEMP.put(bankGroup.getName(), bankGroup);
    // }
    //
    // bankGroup.addBank(bank);
    // }
    //
    // ResultHolder.RESULT_ROW.addAll(banks);
    // ResultHolder.TEMP.clear();
    // }
    //
    // public static BankGroup getBankGroup(int index) {
    // // if ((index < 0) || (index >= ResultHolder.RESULT.size())) {
    // // return null;
    // // }
    //
    // return ResultHolder.RESULT.get(index);
    // }
    //
    // public static List<BankGroup> getAllBankGroups() {
    // return new ArrayList<BankGroup>(ResultHolder.RESULT);
    // }

    public static List<BankomatDto> getAllBanks() {
	return new ArrayList<BankomatDto>(BankomatiResultHolder.RESULT);
    }

    public static GeoPoint getMyGeoPoint() {
	return BankomatiResultHolder.LOCATION;
    }

    public static void clear() {
	// TODO Recycle loaded bitmaps if necessary..

	BankomatiResultHolder.RESULT.clear();
	BankomatiResultHolder.LOCATION = null;
    }
}
